﻿using System;
//using System.Net;
//using System.Windows;
//using System.Windows.Controls;
//using System.Windows.Documents;
//using System.Windows.Ink;
//using System.Windows.Input;
//using System.Windows.Media;
//using System.Windows.Media.Animation;
//using System.Windows.Shapes;
using System.Globalization;

using GeoAPI.CoordinateSystems;
//using GeoAPI.CoordinateSystems.Transformations;
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.CoordinateSystems.Transformations;
//using GisSharpBlog.NetTopologySuite.Geometries;
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;
using Point = System.Windows.Point;


namespace SMIL.Services
{
    public class ArcGISRest : SMILTileSource
    {

        // ArcGIS REST
        //http://fsksapse55/ArcGIS/rest/services/Administrativt/Administrativt/MapServer/export?bbox=1924429.4975401%2C9051326.09842048%2C1932030.46997674%2C9055122.87684737&bboxSR=&layers=show%3A1%2C2&layerdefs=&size=&imageSR=&format=png&transparent=false&dpi=&f=image
        private const string _TILEPATH = @"{ADDRESS}?bbox={BBOX}&bboxSR={BBOXSR}&layers={LAYERS}&layerdefs={LAYERDEFS}&size={SIZE}&imageSR={IMAGESR}&format={FORMAT}&transparent={TRANSPARENT}&dpi={DPI}&f={F}";

        private string _Address;
        private string _Layers;
        private string _Layersdefs;
        private string _bBoxSR;
        private string _ImageSR;
        private string _Format = "png";
        private bool _Transparent = false;
        private string _Dpi;
        //Constructor Called by XAML instantiation;
        public ArcGISRest()
            : base()
        {
        }

        public ArcGISRest(string address, string layers, string layerDefs, string bBoxSR, string imageSR, string format, bool transparent, string dpi, string scaleMin = null, string scaleMax = null )
            : this()
        {
            this._Address = address;
            this._Layers = layers;
            this._Layersdefs = layerDefs;
            this._bBoxSR = bBoxSR;

            this._ImageSR = imageSR;
            if (format.Length > 0)
                this._Format = format;
            this._Transparent = transparent;
            this._Dpi = dpi;
            if ((scaleMin != null) && (scaleMin.Length > 0))
                base.MinZoomLevel = int.Parse(scaleMin);
            if ((scaleMax != null) && (scaleMax.Length > 0))
                base.MaxZoomLevel = int.Parse(scaleMax);
        }

        public string Layers
        {
            get { return _Layers; }
            set { _Layers = value; }
        }


        #region TileSource Overrides

        public override Uri GetUri(int x, int y, int zoomLevel)
        {
            if (((this.MinZoomLevelSet) && (zoomLevel < MinZoomLevel)) || ((this.MaxZoomLevelSet) && (zoomLevel > MaxZoomLevel)))
                return null;

            string quadKey = TileXYToQuadKey(x, y, zoomLevel);

            // Use the quadkey to determine a bounding box for the requested tile
            BBox boundingBox = QuadKeyToBBox(quadKey);

            // Get the lat longs of the corners of the box
            double lon = XToLongitudeAtZoom(boundingBox.x * _TILE_SIZE, 18);
            double lat = YToLatitudeAtZoom(boundingBox.y * _TILE_SIZE, 18);

            double lon2 = XToLongitudeAtZoom((boundingBox.x + boundingBox.width) * _TILE_SIZE, 18);
            double lat2 = YToLatitudeAtZoom((boundingBox.y - boundingBox.height) * _TILE_SIZE, 18);

            ////The SRS for this datasource is EPSG:4326, therefore we need to transfrom it to OSM projection
            //var ctf = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory();
            //var cf = new ProjNet.CoordinateSystems.CoordinateSystemFactory(); 
            //GeographicCoordinateSystem wgs84geo = GeographicCoordinateSystem.WGS84;
            //var target = cf.CreateFromWkt("PROJCS[\"WGS_1984_Web_Mercator_Auxiliary_Sphere\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator_Auxiliary_Sphere\"],PARAMETER[\"False_Easting\",0.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],PARAMETER[\"Standard_Parallel_1\",0.0],PARAMETER[\"Auxiliary_Sphere_Type\",0.0],UNIT[\"Meter\",1.0]]");


            //var ctfac = new CoordinateTransformationFactory();
            //ICoordinateTransformation trans = ctfac.CreateFromCoordinateSystems(wgs84geo, target);
            ////ICoordinateTransformation trans = new CoordinateTransformationFactory().CreateFromCoordinateSystems(wgs84geo, target);

            ////IPoint pUtm = GeometryTransform.TransformPoint(f, pGeo, trans.MathTransform);
            //Point lonlatPnt = trans.MathTransform.Transform(new Point(lon, lat));
            //Point lonlatPnt2 = trans.MathTransform.Transform(new Point(lon2, lat2));

            string url = _TILEPATH;

            url = url.Replace("{ADDRESS}", _Address);
            url = url.Replace("{BBOX}", lon.ToString(CultureInfo.InvariantCulture) + "," + lat.ToString(CultureInfo.InvariantCulture) + "," + lon2.ToString(CultureInfo.InvariantCulture) + "," + lat2.ToString(CultureInfo.InvariantCulture));
            url = url.Replace("{BBOXSR}", "4326");
            url = url.Replace("{LAYERS}", _Layers);
            url = url.Replace("{LAYERDEFS}", _Layersdefs);
            url = url.Replace("{SIZE}", _TILE_SIZE.ToString() + "," + _TILE_SIZE.ToString());
            url = url.Replace("{IMAGESR}", "102100");
            url = url.Replace("{FORMAT}", _Format);
            url = url.Replace("{TRANSPARENT}", "true");
            url = url.Replace("{DPI}", _Dpi);
            url = url.Replace("{F}", "image");


            return new Uri(url);
        }

        #endregion

    }
}
